﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Jinndev.UI;
using System.IO;
using Newtonsoft.Json.Linq;
using System.Collections;

namespace Jinndev {

    /// <summary>
    /// 检查未使用的资源
    /// </summary>
    public class CheckUnusedResUI : BaseUIBehaviour {

        #region static
        public static readonly string PATH = "Prefab/UI/CheckUnusedRes/CheckUnusedResUI";

        public static CheckUnusedResUI Create() {
            return UIManager.Instance.Add<CheckUnusedResUI>(PATH, UIParam.FullScreen);
        }
        #endregion

        public InputField rootDir;
        public InputField checkDir;
        public Image progressBar;
        public Text progressText;
        public Text progressInfoText;
        public Button btnStart;
        public RectTransform logArea;

        private LogView logView;

        private void Awake() {
            Util.InitBrowsePasteDirectory(rootDir, "选择根Bundle文件夹");
            Util.InitBrowsePasteDirectory(checkDir, "选择要检查的文件夹");

            rootDir.onValueChanged.AddListener(Refresh);
            checkDir.onValueChanged.AddListener(Refresh);

            logView = LogView.Create(logArea);

            progressBar.fillAmount = 0;
            progressText.text = string.Empty;
            progressInfoText.text = string.Empty;

            btnStart.interactable = false;
        }

        private void OnDestroy() {

        }

        private void Update() {
            TryInvokeSingleAction();
        }

        private void Refresh(string value) {
            bool enabled = !string.IsNullOrEmpty(rootDir.text) && Directory.Exists(rootDir.text)
                && !string.IsNullOrEmpty(checkDir.text) && Directory.Exists(checkDir.text);
            btnStart.interactable = enabled;
        }

        public void OnClickStart() {
            StartCoroutine(Check());
        }

        private IEnumerator Check() {
            logView.Clear();
            btnStart.interactable = false;

            progressBar.fillAmount = 0;
            progressText.text = string.Empty;
            progressInfoText.text = string.Empty;

            string rootPath = rootDir.text;
            string checkPath = checkDir.text;

            // 资源的uuid与路径映射
            var resUuid2Path = new Dictionary<string, string>();
            string[] metas = Directory.GetFiles(checkPath, "*.meta", SearchOption.AllDirectories);
            for (int i = 0; i < metas.Length; i++) {
                string metaPath = metas[i];
                if (!metaPath.EndsWith("jpg.meta") && !metaPath.EndsWith("png.meta")) {
                    continue;
                }
                string jsonText = File.ReadAllText(metaPath);
                string uuid = CocosUtil.GetResourceUuid(jsonText);

                if (uuid != null) {
                    string resPath = metaPath.Substring(checkPath.Length, metaPath.Length - checkPath.Length - ".meta".Length).Replace("\\", "/");
                    resUuid2Path[uuid] = resPath;
                }
                SetProgressLater(i, metas.Length, "搜集meta");
                yield return new WaitForEndOfFrame();
            }
            logView.Log("UUID数量: " + resUuid2Path.Count);

            // 资源的引用记录<ResUuid, [PrefabPath]>
            var resRefs = new MultiMap<string, string>();
            string[] prefabs = Directory.GetFiles(rootPath, "*.prefab", SearchOption.AllDirectories);
            for (int i = 0; i < prefabs.Length; i++) {
                string prefabFile = prefabs[i];

                string jsonText = File.ReadAllText(prefabFile);
                JArray prefabJson = JArray.Parse(jsonText);
                CocosPrefab prefab = CocosUtil.ParsePrefab(prefabJson, Path.GetFileNameWithoutExtension(prefabFile));
                prefab.ForEachComponent((com) => {
                    var refUuids = com.GetSpriteUuids();
                    foreach (var refUuid in refUuids) {
                        resRefs.Add(refUuid.Value, com.node.Path);
                    }
                });

                SetProgressLater(i, prefabs.Length, "检查引用");
                yield return new WaitForEndOfFrame();
            }

            // 检查未使用的资源
            foreach (var pair in resUuid2Path) {
                if (!resRefs.ContainsKey(pair.Key)) {
                    string resPath = pair.Value;
                    logView.Log(resPath);
                }
            }

            logView.Log("完成");
            btnStart.interactable = true;
        }

        private void SetProgressLater(int index, int total, string info) {
            EnqueueAction(() => {
                progressBar.fillAmount = (float)index / total;
                progressText.text = (index + 1) + "/" + total;
                progressInfoText.text = info;
            });
        }

    }

}
